package com.ebs.md.impl.payload.deal;

/**
 * Perforce Revision:
 *  $File: //depot/MarketData/commons-md-payload-impl/MAIN/src/main/java/com/ebs/md/impl/payload/deal/BasicDealAdapterImpl.java $
 *  $Revision: #3 $  $Change: 116321 $  $DateTime: 2012/10/29 12:24:52 $  $Author: Arik.Sher $
 */

import java.util.Calendar;
import java.util.TimeZone;

import org.apache.log4j.Logger;

import com.ebs.commons.comp.IParsedPayload;
import com.ebs.md.api.Rate;
import com.ebs.md.api.abs.AbsProductProvider;
import com.ebs.md.api.deal.BasicDeal;
import com.ebs.md.api.deal.DealSide;
import com.ebs.md.api.deal.DealSideAction;
import com.ebs.md.api.deal.IDeal;
import com.ebs.md.api.deal.IDealAdapter;
import com.ebs.md.api.product.PairProduct;


/**
 * 
 *
 * @see com.ebs.tdl.input.jarb.PayloadCreator
 * @see message_conversion_properties.xml
 * @see mq_msg_build.xml
 */
public class  BasicDealAdapterImpl
implements   IDealAdapter<IParsedPayload, IDeal>
{
    protected final Logger  logger = Logger.getLogger(getClass());

	static final protected TimeZone gmtTZ = TimeZone.getTimeZone("GMT");

	protected AbsProductProvider<String, PairProduct> pairProductProvider;

	public void setPairProductProvider(AbsProductProvider<String, PairProduct> pairProductProvider) {
		this.pairProductProvider = pairProductProvider;
	}

	protected PairProduct extractProduct(IParsedPayload pp) {
		String  baseCcyIso  = pp.getParsedStringField ( "base_ccy");
		String localCcyIso  = pp.getParsedStringField ("local_ccy");
		int    matchingType = pp.getParsedIntField    ("matching_type");
		
		String productKey = PairProduct.generateKey(baseCcyIso, localCcyIso, matchingType);
		
		PairProduct cachedProduct = pairProductProvider.getProduct(productKey);
		
		if ( cachedProduct == null ) {
			// caching it
			cachedProduct = new PairProduct(baseCcyIso, localCcyIso, matchingType);
			
			pairProductProvider.storeKnownItem(productKey, cachedProduct);
		}
		return cachedProduct;
	}

	/**
	 * 
	 * @param source
	 * @return Taker or Maker. null if non of them!
	 */
	protected DealSide extractDealSide(IParsedPayload source) {
		String mqMsgType = source.getParsedStringField("mq_msg_type");
		//    RDST = _DEALSTATUSTAKER
		if ( "RDST".equals(mqMsgType) ) {
			return DealSide.TAKER;
		}
		//    RDSM = _DEALSTATUSMAKER
		if ( "RDSM".equals(mqMsgType) ) {
			return DealSide.MAKER;
		}
		
		// not DealMessage
		return null;
	}
	
	protected Rate extractRate(IParsedPayload pp) {
		return new Rate(pp.getParsedStringField("prc_deal_value", "0.0"));
	}

	public IDeal convert(IParsedPayload source) {
		DealSide dealSide = extractDealSide(source);
		
		if ( dealSide == null ) {
			return null;
		}
		
		PairProduct product = extractProduct(source);
		String dealId = source.getParsedStringField("deal_id");
		String dealRateStr = source.getParsedStringField("prc_deal_value");
		Rate   dealRate = new Rate(dealRateStr);
		long   amount   = source.getParsedLongField("deal_amt_result", 0);

		long   msgTime  = source.getParsedLongField("deal_completion_time", 0);
		if ( msgTime <= 0 ) {
			msgTime     = source.getParsedLongField("msg_timestamp_long", 0);
		}
		Calendar dealTime = Calendar.getInstance(gmtTZ);
		dealTime.setTimeInMillis(msgTime);

		String dealSideActionStr = source.getParsedStringField("deal_side_value");
		DealSideAction dealSideAction = DealSideAction.getByName(dealSideActionStr);
		
		int    makerFirmId    = source.getParsedIntField   ("maker_virtual_floor_id", 0);
		String makerFloorCode = source.getParsedStringField("maker_floor_code");
		String makerTransId   = source.getParsedStringField("maker_trans_id");
		int    takerFirmId    = source.getParsedIntField   ("taker_virtual_floor_id", 0);
		String takerFloorCode = source.getParsedStringField("taker_floor_code");
		String takerTransId   = source.getParsedStringField("taker_trans_id");
		
		Integer thisFirmId    = nullableFirmId( makerFirmId);
		String  thisFloorCode =  makerFloorCode;
		String  thisOrderId   =  makerTransId;
		
		Integer   cpFirmId    = nullableFirmId( takerFirmId);
		String    cpFloorCode =  takerFloorCode;
		String    cpOrderId   =  takerTransId;
		
		if ( DealSide.TAKER.equals(dealSide) ) {
			thisFirmId    = nullableFirmId( takerFirmId);
			thisFloorCode =  takerFloorCode;
			thisOrderId   =  takerTransId;
			
			  cpFirmId    = nullableFirmId( makerFirmId);
			  cpFloorCode =  makerFloorCode;
			  cpOrderId   =  makerTransId;
		}
		
		BasicDeal basicDeal = new BasicDeal(
			 dealId
			,dealSide
			,dealTime
			,product
			,dealRate
			,amount
			,dealSideAction
			
			,thisFirmId
			,thisFloorCode
			,thisOrderId
			
			,  cpFirmId
			,  cpFloorCode
			,  cpOrderId
			);
		
		return basicDeal; 
	}

	protected Integer nullableFirmId(int primitiveValue) {
		if ( primitiveValue == 0 ) {
			return null;
		} else {
			return Integer.valueOf(primitiveValue);
		}
	}
	
	
}
